home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
scope
/
101-125
/
scopedisk120
/
mrcat
/
arpfilescan.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-19
|
5KB
|
167 lines
/* ArpFileScan
* Filename: ArpFileScan
* Author: Mark R. Rinfret
*
* ArpFileScan builds an expanded list of filenames from a filename argument list.
* It is written to be entirely reentrant.
*/
#include <stdlib.h>
#include <fcntl.h>
#include <ctype.h>
#include <string.h>
#include <exec/types.h>
#include <libraries/arpbase.h>
/* The UserAnchor structure is used by ARP's FindFirst/FindNext routines. */
struct UserAnchor {
struct AnchorPath ua_AP;
BYTE moreMem[255];
};
/* The ListInfo structure tracks our filename list building process. */
typedef struct ListInfo {
char **theList;
int slotCount; /* number of slots in the list. */
int entryCount; /* number of slots filled */
struct DefaultTracker *tracker;
struct UserAnchor anchor;
} ListInfo;
/* FUNCTION
* StoreTracker - get the LastTracker value in register a1.
*
* SYNOPSIS
* struct DefaultTracker *StoreTracker(void);
*
* DESCRIPTION
* StoreTracker is a simple function written in assembly language to provide
* access to the LastTracker item. This method was implemented because the
* ARP method (via IoErr()) is unreliable at this time.
*
* StoreTracker *MUST* be called immediately after a call to an ARP library
* function which allocates a tracker. Otherwise, its results are unreliable.
*/
struct DefaultTracker*
StoreTracker(void)
{
#asm
move.l a1,d0 ; Simulate function result. Is this Lattice-compatible?
#endasm
}
/* FUNCTION
* AddFile - add a filename to the filename list.
*
* SYNOPSIS
* static int AddFile(ListInfo *fileList, const char *theFile);
*
* DESCRIPTION
* AddFile attempts to add <theFile> to the filename list. The list will be
* expanded if necessary.
*
* AddFile returns zero if successful or 1 on error.
*/
static int
AddFile(ListInfo *fileList, const char *theFile)
{
char *fName; /* for a copy of theFile */
char **newList;
int newCount;
size_t newSize;
struct DefaultTracker *newTracker;
if (fileList->entryCount >= fileList->slotCount) { /* Expand the list? */
newCount = fileList->slotCount + 50;
newSize = sizeof(char *) * newCount;
newList = ArpAlloc(newSize);
newTracker = StoreTracker();
if (newList == NULL) return 1; /* Error! */
fileList->slotCount = newCount;
if (fileList->theList) {
/* Copy old stuff to new list. */
memcpy(newList, fileList->theList, newSize);
/* Dispose of the old list. */
FreeTrackedItem(fileList->tracker);
fileList->tracker = newTracker;
}
fileList->theList = newList;
}
fName = ArpAlloc(strlen(theFile)+1);
if (! fName) return 1;
strcpy(fName, theFile);
fileList->theList[fileList->entryCount++] = fName;
return 0;
}
/* FUNCTION
* Compare - perform case-insensitive compare of two filename strings.
*
* SYNOPSIS
* static int Compare(const void *a, const void *b);
*
* DESCRIPTION
* Compare simply provides an interface between qsort() and a string
* comparison routine. It returns the result of the string comparison.
*/
static int
Compare(const void *a, const void *b)
{
return Strcmp(*(char **)a, *(char **)b);
}
/* FUNCTION
* ArpFileScan - scan, expand and optionally sort a file specification list.
*
* SYNOPSIS
* char **ArpFileScan(char **rawList, int rawCount, int *newCount;
* int sortFiles);
*
* DESCRIPTION
* ArpFileScan treats each entry in <rawList> as a file specification and
* attempts to expand it into multiple filenames. The number of entries
* in <rawList> is defined by <rawCount>. If successful, ArpFileScan will
* return a pointer to a new list of filenames, passing the number of entries
* via <newCount>. If <sortFiles> is non-zero, the list will be sorted.
*
* If ArpFileScan is unable to perform an allocation, NULL is returned.
*/
char **
ArpFileScan(char **rawList, int rawCount, int *newCount, int sortFiles)
{
ListInfo fileList; /* Stack-based for reentrancy. */
int rawIndex = 0;
int result;
char *rawName;
fileList.theList = NULL; /* Initialize the list structure. */
fileList.slotCount = 0;
fileList.entryCount = 0;
fileList.anchor.ua_AP.ap_StrLen = 255; /* Want full path built. */
fileList.anchor.ua_AP.ap_BreakBits |= (SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D);
while (rawIndex < rawCount) {
rawName = rawList[rawIndex++];
result = FindFirst(rawName, (struct AnchorPath *) &fileList.anchor);
while (result == 0) {
if (AddFile(&fileList, (const char *) &fileList.anchor.ua_AP.ap_Buf))
return NULL;
result = FindNext((struct AnchorPath *) &fileList.anchor);
}
}
*newCount = fileList.entryCount;
if (fileList.theList && sortFiles) {
qsort(fileList.theList, fileList.entryCount, sizeof(char *), Compare);
}
return fileList.theList;
}